The internal/ package enforces compile-time import restrictions within a module. Minimizing exported identifiers and using unexported types is Go's primary API boundary mechanism.
Unexported identifiers are free to change without versioning concerns — keep implementation details unexported
Exported identifiers form a contract — once published, changing them requires a major version bump
Accept interfaces, return concrete types in public APIs for flexibility
Use internal/ for shared code across services in the same module without exposing it publicly
Document exported identifiers — godoc generates documentation from exported types and functions